﻿using System;
using System.Diagnostics;

namespace CommonUtils
{
    /// <summary>
    /// 控制台相关方法
    /// </summary>
    public static class ConsoleUtil
    {
        enum Level
        {
            Info,
            Warining,
            Error
        }

        /// <summary>
        /// 打印开关，只对打印生效，写入照常
        /// 关写入要去LogUtil
        /// </summary>
        public static bool Close = false;

        /// <summary>
        /// 不区分大小写
        /// </summary>
        public static bool YesOrNo()
        {
            while (true)
            {
                WriteLine("Y/N?");
                var key = Console.ReadKey().Key;
                WriteLine();
                if (key == ConsoleKey.Y)
                    return true;
                if (key == ConsoleKey.N)
                    return false;
            }
        }

        public static bool InputYesOrNo()
        => YesOrNo();

        /// <summary>
        /// 控制台暂停
        /// </summary>
        public static void Pause(string tip = null)
        {
            if (!string.IsNullOrEmpty(tip))
                WriteLine(tip);

            WriteLine("Press enter to continue...");
            Console.ReadLine();
        }

        public static void PauseEcpextInputExit(Action<string> action = null)
        {
            WriteLine("Input exit to quit...");

            var input = Console.ReadLine();

            while (input != "exit")
            {
                action?.Invoke(input);
                input = Console.ReadLine();
            }
        }

        public static void ExitAfterInput(Action<string> action = null)
        => PauseEcpextInputExit(action);

        public static event Action<string> OnWrite;

        private static void Write(Level level, object value, params object[] args)
        {
            if (Close) return;

            //json中的花括号会引发异常，所以加个args判断，一般json不会有args
            var msg = args.Length > 0 ? string.Format(value.ToStringEx(), args) : value.ToStringEx();

            switch (level)
            {
                case Level.Warining:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    break;
                case Level.Error:
                    Console.ForegroundColor = ConsoleColor.Red;
                    break;
                default:
                    Console.ForegroundColor = ConsoleColor.Green;
                    break;
            }

            Console.Write(msg);

            //Console.ResetColor();

            Debug.Write(msg);

            OnWrite?.Invoke(msg);
        }

        public static void Write(object value, params object[] args)
        => Write(Level.Info, value, args);

        public static void WriteLine(object value = null, params object[] args)
        => Write(value + StringIdentifier.NewLine + StringIdentifier.NewLine, args);

        private static void WriteLine(Level level, object value = null, params object[] args)
        => Write(level, value + StringIdentifier.NewLine + StringIdentifier.NewLine, args);

        public static void Info(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void Warn(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void Error(object value, params object[] args)
        => WriteLine(Level.Info, value, args);

        public static void WriteJson(object value)
        => WriteLine(value.ToJson());

        public static void WriteHello()
        => WriteLine("Hello! " + ApplicationUtil.Name);

        public static void WriteTime()
        => WriteLine(DateTime.Now.FullInfo());
    }
}
